package com.zvezda.http.utils;


import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketTimeoutException;
import java.net.URI;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;

import android.os.Bundle;
import android.os.Message;
import android.util.Log;


/**
 * 现在数据的线程
 * 
 * @author Zvezda
 *
 */
public class RequestFileRunnable implements Runnable
{
	/**
	 * 请求Http的数据监听接口
	 */
	private RequestHttpListener requestHttpListener = null;

	/**
	 * 请求网址
	 */
	private String fileUrl = "";

	/**
	 * 文件保存的本地地址
	 */
	private String filePath = "";

	/**
	 * 当前已经下载的字节数
	 */
	private long currentLength = 0;

	/**
	 * 总的字节数
	 */
	private long totalLength = 0;

	/**
	 * 请求方式
	 */
	private String requestMethod = "GET";

	/**
	 * 请求超时时间为30秒
	 */
	private int requestTime = 15000;

	/**
	 * 连接超时时间为30秒
	 */
	private int connectTime = 15000;

	/**
	 * 无错误
	 */
	private int errorType = HttpConst.ERROR_NO;

	/**
	 * 请求参数
	 */
	private DefaultHttpClient httpClient = new DefaultHttpClient();

	/**
	 * 请求文件的线程
	 * 
	 * @param requestHttpListener
	 * @param fileUrl
	 * @param filePath
	 */
	public RequestFileRunnable(RequestHttpListener requestHttpListener, String fileUrl, String filePath)
	{
		this.requestHttpListener = requestHttpListener;
		this.fileUrl = fileUrl;
		this.filePath = filePath;
		currentLength = 0;
		totalLength = 0;
	}

	/**
	 * 获得cook
	 * 
	 * @return
	 */
	public CookieStore getCookieStore()
	{
		if (httpClient != null)
		{
			return httpClient.getCookieStore();
		}
		return null;
	}

	/**
	 * 设置cookieStore
	 * 
	 * @param cookieStore
	 */
	public void setCookieStore(CookieStore cookieStore)
	{
		if (httpClient != null)
		{
			httpClient.setCookieStore(cookieStore);
		}
	}

	/**
	 * 用httpClient请求
	 */
	private void httpClientGetData()
	{
		try
		{
			URI encodedUri = null;
			HttpGet httpGet = null;
			encodedUri = new URI(fileUrl);
			httpGet = new HttpGet(encodedUri);
			// 请求超时
			httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, requestTime);
			// 读取超时
			httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, connectTime);
			HttpResponse httpResponse = null;
			// 执行请求
			httpResponse = httpClient.execute(httpGet);
			// 请求数据
			HttpEntity httpEntity = httpResponse.getEntity();
			int resultCode = httpResponse.getStatusLine().getStatusCode();
			switch (resultCode)
			{
				case HttpStatus.SC_OK:
					if (httpEntity != null)
					{
						InputStream is = httpEntity.getContent();
						FileOutputStream fos = new FileOutputStream(filePath);
						byte[] buffer = new byte[1024];
						int len = 0;
						currentLength = len;
						totalLength = httpEntity.getContentLength();
						while ((len = is.read(buffer)) != -1)
						{
							fos.write(buffer, 0, len);
							currentLength = currentLength + len;
							sendMsg(HttpConst.ACTION_TRANSFER);
						}
						fos.close();
						is.close();
						sendMsg(HttpConst.ACTION_SUCCESS);
					}
					else
					{
						sendMsg(HttpConst.ACTION_FAIL);
					}
					break;
				case 401:// 未授权
				case 500:// 服务器内部错误
				case 404:// 找不到网页
				case 505:// 访问的网站当前没有显示该网页的功能
				default:
					Log.e(HttpConst.HTTP_LOG, getClass().getSimpleName() + "  Request Lose--------------------->" + resultCode);
					errorType = HttpConst.ERROE_RESPONSE;
					sendMsg(HttpConst.ACTION_FAIL);
					break;
			}
		}
		catch (SocketTimeoutException se)
		{
			Log.e(HttpConst.HTTP_LOG,
					getClass().getSimpleName() + "  SocketTimeoutException--------------------->" + se.toString());
			errorType = HttpConst.ERROR_TIME_OUT;
			sendMsg(HttpConst.ACTION_FAIL);
		}
		catch (IOException e)
		{
			Log.e(HttpConst.HTTP_LOG, getClass().getSimpleName() + "  IOException--------------------->" + e.toString());
			errorType = HttpConst.ERROR_IO;
			sendMsg(HttpConst.ACTION_FAIL);
		}
		catch (Exception e)
		{
			Log.e(HttpConst.HTTP_LOG, getClass().getSimpleName() + "  Exception--------------------->" + e.toString());
			errorType = HttpConst.ERROR_OTHER;
			sendMsg(HttpConst.ACTION_FAIL);
		}
	}

	// /**
	// * 另外的请求方式
	// */
	// private void httpURLConnectionGetData()
	// {
	// HttpURLConnection conn = null;
	// InputStream is = null;
	// try
	// {
	// System.out.println("--------->"+urlPath);
	// URL url = new URL(urlPath);
	// conn = (HttpURLConnection)url.openConnection();
	// conn.setRequestMethod(requestMethod);
	// conn.setConnectTimeout(connectTime);
	// conn.setReadTimeout(requestTime);
	// int resultCode = conn.getResponseCode();
	// switch(resultCode)
	// {
	// case 200://读取成功
	// is = conn.getInputStream();
	// ByteArrayOutputStream baos = new ByteArrayOutputStream();
	// byte[] buffer = new byte[1024];
	// int len = 0;
	// while ((len = is.read(buffer)) != -1)
	// {
	// baos.write(buffer, 0, len);
	// }
	// baos.flush();
	// sendMsg(HttpRequestConstant.ACTION_OK,baos.toByteArray());
	// baos.close();
	// is.close();
	// break;
	// case 401://未授权
	// case 500://服务器内部错误
	// case 404://找不到网页
	// case 505://访问的网站当前没有显示该网页的功能
	// default:
	// Log.e(HttpRequestConstant.HTTP_LOG,
	// getClass().getSimpleName()+"  Request Lose--------------------->"+resultCode);
	// errorType = HttpRequestConstant.ERROE_RESPONSE;
	// sendMsg(HttpRequestConstant.ACTION_LOSE,null);
	// break;
	// }
	// }
	// catch (SocketTimeoutException se)
	// {
	// Log.e(HttpRequestConstant.HTTP_LOG,
	// getClass().getSimpleName()+"  SocketTimeoutException--------------------->"+se.toString());
	// errorType = HttpRequestConstant.ERROR_TIME_OUT;
	// sendMsg(HttpRequestConstant.ACTION_LOSE,null);
	// }
	// catch (IOException e)
	// {
	// Log.e(HttpRequestConstant.HTTP_LOG,
	// getClass().getSimpleName()+"  IOException--------------------->"+e.toString());
	// errorType = HttpRequestConstant.ERROR_IO;
	// sendMsg(HttpRequestConstant.ACTION_LOSE,null);
	// }
	// catch (Exception e)
	// {
	// Log.e(HttpRequestConstant.HTTP_LOG,
	// getClass().getSimpleName()+"  Exception--------------------->"+e.toString());
	// errorType = HttpRequestConstant.ERROR_OTHER;
	// sendMsg(HttpRequestConstant.ACTION_LOSE,null);
	// }
	// }
	@Override
	public void run()
	{
		// TODO Auto-generated method stub
		httpClientGetData();
		// httpURLConnectionGetData();
	}

	/**
	 * 返回读取数据的结果
	 * 
	 * @param result
	 * @param dataArr
	 */
	private void sendMsg(int result)
	{
		if (requestHttpListener != null)
		{
			Bundle bundle = new Bundle();
			bundle.putInt(HttpConst.ACTION_RESULT, result);
			bundle.putInt(HttpConst.ERROR_TYPE, errorType);
			bundle.putString(HttpConst.FILE_PATH, filePath);
			bundle.putString(HttpConst.FILE_URL, fileUrl);
			bundle.putLong(HttpConst.CURRENT_LENGTH, currentLength);
			bundle.putLong(HttpConst.TOTAL_LENGTH, totalLength);
			Message msg = new Message();
			msg.setData(bundle);
			requestHttpListener.requestHttp(msg);
		}
	}

	/**
	 * 获得请求的监听接口
	 * 
	 * @return
	 */
	public RequestHttpListener getRequestHttpListener()
	{
		return requestHttpListener;
	}

	/**
	 * 设置请求的监听接口
	 */
	public void setRequestHttpListener(RequestHttpListener requestHttpListener)
	{
		this.requestHttpListener = requestHttpListener;
	}

	/**
	 * 获得请求的网址
	 * 
	 * @return
	 */
	public String getUrlPath()
	{
		return fileUrl;
	}

	/**
	 * 设置请求的网址
	 * 
	 * @param urlPath
	 */
	public void setUrlPath(String urlPath)
	{
		this.fileUrl = urlPath;
	}

	/**
	 * 获得请求的方式
	 * 
	 * @return
	 */
	public String getRequestMethod()
	{
		return requestMethod;
	}

	/**
	 * 设置请求的方式
	 * 
	 * @param requestMethod
	 */
	public void setRequestMethod(String requestMethod)
	{
		this.requestMethod = requestMethod;
	}

	/**
	 * 获得请求超时的时间
	 * 
	 * @return
	 */
	public int getRequestTime()
	{
		return requestTime;
	}

	/**
	 * 设置请求超时的时间
	 * 
	 * @param requestTime
	 */
	public void setRequestTime(int requestTime)
	{
		this.requestTime = requestTime;
	}

	/**
	 * 获得连接超时的时间
	 * 
	 * @return
	 */
	public int getConnectTime()
	{
		return connectTime;
	}

	/**
	 * 设置连接超时的时间
	 * 
	 * @param connectTime
	 */
	public void setConnectTime(int connectTime)
	{
		this.connectTime = connectTime;
	}
}